//
//  Home.swift
//  ScratchCard
//
//  Created by 云控蜂核 on 2023/5/7.
//

import SwiftUI

struct Home: View {
    
    @State var onfinish: Bool = false
    
    var body: some View {
        
        VStack{
            
            //scratch Card View
            
            ScratchCardView(cursorSize: 50, onfinish: $onfinish) {
                //body content
                VStack{
                    Image("trophy")
                        .resizable()
                        .aspectRatio(contentMode: .fit)
                        .padding(10)
                    Text("Your")
                        .font(.largeTitle)
                        .fontWeight(.bold)
                        .foregroundColor(.gray)
                    Text("$199")
                        .font(.title)
                        .fontWeight(.bold)
                        .foregroundColor(.gray)
                        .padding(.top, 5)
                    
                }
                .padding()
                .frame(maxWidth: .infinity, maxHeight: .infinity)
                .background(Color.white)
                
                
            } overlayView: {
                
                // overlay image or view
                
                Image("scratch")
                    .resizable()
                    .aspectRatio(contentMode: .fill)
            }

            
        }
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.black)
        .overlay(alignment: .top) {
            HStack(spacing: 15){
                Button {
                    
                } label: {
                    Image(systemName: "xmark")
                        .font(.title2)
                        .foregroundColor(.white)
                }
                
                Text("Scratch Card")
                    .font(.title2)
                    .fontWeight(.semibold)
                    .foregroundColor(.white)
                
                Spacer()
                
                Button {
                    onfinish = false
                } label: {
                    Image("pic")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(width: 55, height: 55)
                        .clipShape(Circle())
                    
                }
            }
            .padding()
        }
    }
}

struct Home_Previews: PreviewProvider {
    static var previews: some View {
        Home()
    }
}

//custom view...
//Using View builder...

struct ScratchCardView<Content: View,  OverlayView: View>: View {
    
    var content: Content
    var overlayView: OverlayView
    
    init(cursorSize: CGFloat, onfinish: Binding<Bool>, @ViewBuilder content: @escaping ()-> Content, @ViewBuilder overlayView: @escaping ()-> OverlayView) {
        self.content = content()
        self.overlayView = overlayView()
        self.cursorSize = cursorSize
        self._onfinish = onfinish
    }
    
    //for scratch effect...
    @State var startingPoint: CGPoint = .zero
    @State var points: [CGPoint] = []
    
    //for gesture update
    @GestureState var gestureLocation: CGPoint = .zero
    
    // customisation and on finish...
    var cursorSize: CGFloat
    @Binding var onfinish: Bool
    
    var body: some View{
        ZStack{
            overlayView
                .opacity(onfinish ? 0 : 1)
            //login is when user starts scratching the main content will starts visible
            //based on the user drag location...
            //and showing full content when the user releases the drags..
            
            
            content
                .mask(
                    ZStack{
                        if !onfinish {
                            ScratchMask(points: points, startingPoint: startingPoint)
                                .stroke(style: StrokeStyle(lineWidth: cursorSize, lineCap:.round, lineJoin: .round))
                        }else{
                            Rectangle()
                        }
                    }
                    
                )
                .animation(.easeInOut, value: 0.5)
                .gesture(
                    DragGesture()
                        .updating($gestureLocation, body: { value, out, _ in
                            out = value.location
                            
                            DispatchQueue.main.async {
                                //updating starting point
                                //and adding user drag locations...
                                if startingPoint == .zero{
                                    startingPoint = value.location
                                }
                                points.append(value.location)
                            }
                            
                        })
                        .onEnded({ value in
                            withAnimation {
                                onfinish = true
                            }
                        })
                )
            
            
                
            
        }
        .frame(width:300, height: 300)
        .cornerRadius(20)
        .onChange(of: onfinish) { value in
            if !onfinish && !points.isEmpty{
                withAnimation(.easeInOut) {
                    resetView()
                }
            }
        }
        
    }
    
    func resetView() {
        points.removeAll()
        startingPoint = .zero
    }
    
}

//scratch mask shape...
// it will appear based on user gesture

struct ScratchMask: Shape{
    var points: [CGPoint]
    var startingPoint: CGPoint
    
    func path(in rect: CGRect) -> Path {
        return Path { path in
            path.move(to: startingPoint)
            path.addLines(points)
        }
    }
    
}
